<html>
<head><meta charset="utf-8"><title>const generics as ordinary parameters · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html">const generics as ordinary parameters</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="238183420"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238183420" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238183420">(May 10 2021 at 17:47)</a>:</h4>
<p>IIUC, the resolution to "Use const generics for stdarch intrinsics" ( <a href="https://github.com/rust-lang/rust/issues/83167#issuecomment-819627409">https://github.com/rust-lang/rust/issues/83167#issuecomment-819627409</a> ) involves permanently committing to allowing a function defined like <code>fn my_simd_thing&lt;const B: i32&gt;(a: Foo, c: Foo)</code> to be called via <code>my_simd_thing(Foo, 42, Foo)</code> instead of requiring <code>my_simd_thing::&lt;42&gt;(Foo, Foo)</code>. This conclusion was reached not only because chip vendors document these functions as being callable like <code>my_simd_thing(Foo, 42, Foo)</code> (C/C++ then use textual macros to appropriately interpret the const args at compile time), but also because users registered annoyance at the excessive use of the turbofish in their code.</p>
<p>Right now these SIMD functions achieve this behavior via a rustc-only <code>#[rustc_legacy_const_generics]</code> attribute that rewrites <code>my_simd_thing(Foo, 42, Foo)</code> to <code>my_simd_thing::&lt;42&gt;(Foo, Foo)</code>. There has been mention of supporting this as a first-class mechanism so that user code could benefit from this behavior; I've created this thread because I'm not aware of it yet being properly discussed anywhere.</p>
<p>This behavior does have precedence:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Foo</span><span class="o">&gt;</span><span class="p">(</span><span class="n">x</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// predeclared type parameter</span>
<span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="nc">impl</span><span class="w"> </span><span class="n">Foo</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// inline type parameter</span>
<span class="k">fn</span> <span class="nf">foo</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="p">(</span><span class="n">x</span>: <span class="kp">&amp;</span><span class="nc">Foo</span><span class="p">,</span><span class="w"> </span><span class="n">y</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">a</span> <span class="nc">Foo</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="o">'</span><span class="na">a</span> <span class="nc">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// predeclared lifetime parameter</span>
<span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="kp">&amp;</span><span class="nc">Foo</span><span class="p">,</span><span class="w"> </span><span class="n">y</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">a</span> <span class="nc">Foo</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="o">'</span><span class="na">a</span> <span class="nc">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// inline lifetime parameter (accepted by RFC 2115 but not implemented)</span>
</code></pre></div>
<p>At the risk of kicking off a bikeshed, the natural syntax that comes to mind is this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">my_simd_thing</span><span class="p">(</span><span class="n">a</span>: <span class="nc">Foo</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">B</span>: <span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">c</span>: <span class="nc">Foo</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</code></pre></div>
<p>...implying that parameters declared <code>const</code> are parsed as constant type parameters rather than as ordinary parameters (so no pattern-based destructuring, etc.).</p>
<p>Some additional questions:</p>
<ol>
<li>is <code>fn foo&lt;const A: i32&gt;(const B: i32)</code> allowed?</li>
<li>is <code>fn foo&lt;T&gt;(x: [T; const S: usize])</code> allowed?</li>
<li>for <code>fn foo(const A: i32)</code>, can this be called as <code>foo::&lt;42&gt;()</code>?</li>
</ol>
<p>The precedence set by <code>impl Trait</code> in argument position suggests that the respective answers to these are "yes", "yes", and "no".</p>
<p>That last "no" might be a problem; AIUI the resolution to <a href="https://github.com/rust-lang/rust/issues/83167">https://github.com/rust-lang/rust/issues/83167</a> is that the SIMD functions will support <em>both</em> <code>foo(42)</code> and <code>foo::&lt;42&gt;()</code>, meaning that they would not be able to make use of this feature (although it seems like it would be harmless to extend the feature to allow the turbofish when there's exactly one constant parameter, which I think covers all the SIMD functions? <span class="user-mention" data-user-id="143274">@Amanieu</span> ?). But if people didn't want to allow the turbofish to be used with functions declared in this way, then that might be something to address before <code>#[rustc_legacy_const_generics]</code> reaches a stable release.</p>



<a name="238185628"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238185628" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238185628">(May 10 2021 at 18:01)</a>:</h4>
<p>Prior art: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1045r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1045r1.html</a></p>



<a name="238189931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238189931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238189931">(May 10 2021 at 18:28)</a>:</h4>
<p><span class="user-mention silent" data-user-id="229517">Jacob Lifshay</span> <a href="#narrow/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters/near/238185628">said</a>:</p>
<blockquote>
<p>Prior art: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1045r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1045r1.html</a></p>
</blockquote>
<p>Am I correct in thinking that the only shared motivation here is "Better user experience due to uniform syntax on the caller's side"? I don't know much about C++ constexpr, but it looks like most of what that paper aims to address is already a non-issue in Rust const contexts. But I haven't yet read the whole thing.</p>



<a name="238190346"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238190346" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238190346">(May 10 2021 at 18:31)</a>:</h4>
<p>New question, does this work?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="p">[</span><span class="kt">i32</span><span class="p">;</span><span class="w"> </span><span class="n">S</span><span class="p">],</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">S</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</code></pre></div>
<p>A naive approach to desugaring would suggest "yes", although it is a bit curious.</p>



<a name="238190662"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238190662" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lqd <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238190662">(May 10 2021 at 18:33)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters/near/238183420">said</a>:</p>
<blockquote>
<p>although it seems like it would be harmless to extend the feature to allow the turbofish when there's exactly one constant parameter, which I think covers all the SIMD functions?</p>
</blockquote>
<p>most of the stdarch intrinsics using const parameters have a single const parameter, but not all:</p>
<ul>
<li>around 110 have 2 parameters</li>
<li>around 10 have 3</li>
</ul>



<a name="238194537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238194537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238194537">(May 10 2021 at 19:00)</a>:</h4>
<p>good to know. still, from the perspective of backcompat, it wouldn't be a out of the question to conservatively say that the turbofish can only be used with such functions when all type parameters are consts, and must be provided in the order they are declared. that avoids needing to wade into the generally-open const param/type param ordering question.</p>



<a name="238196270"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238196270" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238196270">(May 10 2021 at 19:12)</a>:</h4>
<p>this would also be somewhat surprising with higher-order functions. <code>fn foo(x: i32, const Y: usize, z: i32)</code> would have a function pointer type of <code>fn(i32, i32)</code>, not <code>fn(i32, usize, i32)</code>. I suppose you <em>might</em> be able to allow this function item to coerce to a function pointer of type <code>fn(i32, usize, i32)</code>?</p>



<a name="238196731"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238196731" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238196731">(May 10 2021 at 19:15)</a>:</h4>
<p>surprisingly this last thing isn't a problem for the SIMD functions, trying to coerce them to a function pointer gives me an error that I've never seen before:</p>
<div class="codehilite"><pre><span></span><code>error: this function can only be invoked directly, not through a function pointer
  --&gt; src/main.rs:13:17
   |
13 |         let _ = _mm_shuffle_ps;
   |                 ^^^^^^^^^^^^^^
</code></pre></div>
<p>so I guess "just don't let functions using this feature be used as function pointers" is also one answer, although a somewhat unsatisfying one.</p>



<a name="238206137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238206137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238206137">(May 10 2021 at 20:26)</a>:</h4>
<p>Hmm, I think I'm coming around to the "pass a const as a normal argument", but I think to be happy with that I'd want it to not be declared in the <code>&lt;&gt;</code>s like a generic param.</p>



<a name="238206219"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238206219" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238206219">(May 10 2021 at 20:26)</a>:</h4>
<p>It really makes me want something APIT-like.</p>



<a name="238206519"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238206519" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238206519">(May 10 2021 at 20:28)</a>:</h4>
<p>APIT?</p>



<a name="238206956"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238206956" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238206956">(May 10 2021 at 20:31)</a>:</h4>
<p>Argument-position impl trait.</p>



<a name="238207474"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238207474" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238207474">(May 10 2021 at 20:34)</a>:</h4>
<p>Makes me ponder restrictions like "<code>foo(x)</code> can't return a <code>[T; x]</code>" because then it's behaving less like a runtime value and more like a generic param, and thus <code>foo::&lt;x&gt;()</code> might be more appropriate.</p>



<a name="238207544"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238207544" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238207544">(May 10 2021 at 20:35)</a>:</h4>
<p>All these cases in SIMD are things that don't even get reflected in return types, right?</p>



<a name="238307819"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238307819" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238307819">(May 11 2021 at 13:35)</a>:</h4>
<p>for simd yes, for other const generics that's not always the case</p>



<a name="238321021"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238321021" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> varkor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238321021">(May 11 2021 at 14:52)</a>:</h4>
<blockquote>
<p>There has been mention of supporting this as a first-class mechanism so that user code could benefit from this behavior; I've created this thread because I'm not aware of it yet being properly discussed anywhere.</p>
</blockquote>
<p>It was discussed (and if I recall there was general agreement that) we should try to convert these to const generics. Coming up with stable syntax for them is moving in the wrong direction in my opinion.</p>



<a name="238321368"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238321368" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> varkor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238321368">(May 11 2021 at 14:54)</a>:</h4>
<p>Oh, I see, there have been updates since then. I thought I was subscribed to this issue, but apparently not.</p>



<a name="238321895"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238321895" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> varkor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238321895">(May 11 2021 at 14:58)</a>:</h4>
<p>If new syntax is introduced, you essentially now have two syntaxes for const generics: I don't see that there would be a good reason to restrict this just to stdarch intrinsics.</p>



<a name="238322040"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238322040" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> varkor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238322040">(May 11 2021 at 14:58)</a>:</h4>
<p>(It's not clear to me whether the suggestion is to restrict this syntax to intrinsics or not.)</p>



<a name="238322216"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238322216" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> varkor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238322216">(May 11 2021 at 15:00)</a>:</h4>
<p>I think there are problems with inconsistency and learnability if you make a change like this without also allowing type parameters to be passed as ordinary arguments.</p>



<a name="238324697"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238324697" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> varkor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238324697">(May 11 2021 at 15:13)</a>:</h4>
<p>(Though maybe allowing that wouldn't be a bad thing.)</p>



<a name="238340728"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238340728" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238340728">(May 11 2021 at 16:46)</a>:</h4>
<p>Well you can pass an impl Trait in arg position already.</p>



<a name="238341124"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/238341124" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#238341124">(May 11 2021 at 16:48)</a>:</h4>
<p>And consts are values and other function args are values, but types are not values.</p>
<p>So we don't teach "some turbofish things can be passed as an arg", that <em>would</em> feel inconsistent. Instead we teach "values go in arg position, and if you want even const values can go in arg position".</p>



<a name="239467673"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/239467673" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#239467673">(May 19 2021 at 17:48)</a>:</h4>
<p>I think the sanity here depends on how the API for more complex const generic arguments, like parameterizing over <code>[T; N]</code>, shakes out.</p>



<a name="239553747"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/239553747" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> XAMPPRocky <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#239553747">(May 20 2021 at 08:32)</a>:</h4>
<p>I agree with <span class="user-mention" data-user-id="121053">@varkor</span> that would be inconsistent to have both, and I don't currently see how "const generics in argument position" wouldn't be able to cover all of the cases that currently possible with turbofish. Considering the following code, how would you write it with argument position consts?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">init</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nb">Default</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="kt">bool</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">N</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">4</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">init_functions</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="w"></span>
<span class="w">        </span><span class="n">init</span>::<span class="o">&lt;</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="n">init</span>::<span class="o">&lt;</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="o">&gt;</span><span class="w"></span>
<span class="w">    </span><span class="p">];</span><span class="w"></span>

<span class="w">    </span><span class="k">for</span><span class="w"> </span><span class="n">init</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">init_functions</span><span class="p">.</span><span class="n">iter</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="n">init</span><span class="p">)());</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="239734420"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/239734420" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hannahE2 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#239734420">(May 21 2021 at 11:26)</a>:</h4>
<blockquote>
<p>Considering the following code, how would you write it with argument position consts?</p>
</blockquote>
<p>Why do you care about being able to write that code with argument position consts ?</p>
<p>You would just write:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">init</span>::<span class="o">&lt;</span><span class="kt">u8</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">4</span><span class="p">));</span><span class="w"></span>
<span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">init</span>::<span class="o">&lt;</span><span class="kt">u8</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span><span class="w"></span>
</code></pre></div>



<a name="239734532"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/239734532" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hannahE2 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#239734532">(May 21 2021 at 11:27)</a>:</h4>
<p>How do you write code like this in Rust today ?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">init</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nb">Default</span><span class="o">&gt;</span><span class="p">(</span><span class="n">x</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>

<span class="kd">let</span><span class="w"> </span><span class="n">tys</span>: <span class="p">[</span><span class="nb">Default</span><span class="p">;</span><span class="w"> </span><span class="n">_</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="kt">f32</span><span class="p">];</span><span class="w"></span>
<span class="k">for</span><span class="w"> </span><span class="n">ty</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">tys</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">init</span><span class="p">(</span><span class="k">type</span>::<span class="n">default</span><span class="p">());</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>I don't see much difference between that and const generics in argument position.</p>



<a name="239734857"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/239734857" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hannahE2 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#239734857">(May 21 2021 at 11:30)</a>:</h4>
<p>If you want to support that, it sounds more natural to make kinds first class values.</p>



<a name="239734988"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/239734988" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hannahE2 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#239734988">(May 21 2021 at 11:31)</a>:</h4>
<p>Then your example can just be written as:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">for</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">init</span>::<span class="o">&lt;</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="o">&gt;</span><span class="p">();</span><span class="w">  </span><span class="c1">// not using const generic arguments</span>
<span class="w">    </span><span class="n">init</span>::<span class="o">&lt;</span><span class="kt">u8</span><span class="o">&gt;</span><span class="p">(</span><span class="n">v</span><span class="p">);</span><span class="w">    </span><span class="c1">// using const generic arguments</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>independently of whether you are using const generic arguments or not.</p>
<p>Here the type of <code>(4, 5)</code> would be <code>(const 4: i32, const 5: i32)</code> and <code>for</code> would "monomorphize" its body once for every iteration.</p>
<p>You could emulate this with a macro today.</p>



<a name="239781151"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/239781151" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> XAMPPRocky <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#239781151">(May 21 2021 at 16:52)</a>:</h4>
<blockquote>
<p>Why do you care about being able to write that code with argument position consts ?</p>
</blockquote>
<p><span class="user-mention" data-user-id="409057">@hannahE2</span> It’s just a minimal example of a broader issue with the proposal that const generics are currently defined at the type position, and where the type is defined is different from where it’s called. Of course you can rewrite this example to use call sites, but what if this loop is in a external crate and you just provide init functions array, and you can’t change it? How are you going to define the const argument then?</p>



<a name="239781951"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/239781951" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> XAMPPRocky <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#239781951">(May 21 2021 at 16:58)</a>:</h4>
<p>Also fwiw I have written and do want to write similar code to this as part of my ASN.1 codec framework.</p>



<a name="239783735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/const%20generics%20as%20ordinary%20parameters/near/239783735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/const.20generics.20as.20ordinary.20parameters.html#239783735">(May 21 2021 at 17:12)</a>:</h4>
<p>So, one possible solution is for arg-position consts to be automatically transferrable to the end of the generics list of the function signature for cases where a person needs to do so.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">y</span>: <span class="nc">const</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="c1">// can be used as</span>
<span class="k">fn</span> <span class="nf">foo</span><span class="o">&lt;</span><span class="k">const</span><span class="w"> </span><span class="n">y</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="p">(</span><span class="n">x</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">bar</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">p</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">i</span>: <span class="nc">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="c1">// can be used as</span>
<span class="k">fn</span> <span class="nf">bar</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">i</span>: <span class="kt">u8</span><span class="o">&gt;</span><span class="p">(</span><span class="n">p</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
</code></pre></div>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>